/**
 * Created by yanghaijin on 2018/5/16.
 */

let TenThirtyRoom = require('./../logic/TenThirtyRoom');
const MsgCode = require('./../../../define/MsgCode');
const ErrorCode = require('./../../../define/ErrorCode');
const CodeString = require('./../../../define/CodeString');
const MAP_ID = require('./../../../define/MAP_ID');

module.exports = function (app) {
    return new Remote(app);
};

let Remote = function (app) {
    this.app = app;
    this.map_id = MAP_ID.TEN_THIRTY;
    this.channelService = app.get('channelService');
};

/**
 * 发送消息
 * @param {String | Number} room_id
 * @param {Object} msg
 * @param {Array | String} [uids]
 * */
Remote.prototype.send = function (room_id, msg, uids) {
    let channel = this.channelService.getChannel(room_id, false);
    if (!channel) {
        console.info('不存在该通信信道');
        return;
    }
    if (typeof data === 'undefined') {
        data = {};
    }
    if (typeof uids === 'undefined') {
        uids = channel.getMembers();
    }
    if (!Array.isArray(uids)) {
        uids = [uids];
    }

    console.info('Room send uids: ', uids, ' | room_id: ', room_id);

    let receiver_list = [];
    for (let i = 0; i < uids.length; i++) {
        // let channel = this._channelService.getChannel(room_id, false);
        let member = channel.getMember(uids[i]);
        if (member) {
            let obj = {};
            obj.uid = uids[i];
            obj.sid = member['sid'];
            receiver_list.push(obj);
        }
    }
    this.channelService.pushMessageByUids('onNotify', msg, receiver_list, null, null);
};

/**
 * 创建房间
 * @param {Object} info 玩家信息
 * @param {String} sid server id
 * @param {String} room_id channel name
 * @param {Object} options
 * @param {Function} callback
 */
Remote.prototype.createRoom = function (info, sid, room_id, options, callback) {
    let uid = info['uid'];
    let channel = this.channelService.getChannel(room_id, true);
    if (!!channel) {
        channel.add(uid, sid);
        if (!this.app.roomid2room[room_id]) {
            options.room_id = room_id;
            this.app.roomid2room[room_id] = new TenThirtyRoom(this.app, options);
        }
        this.app.roomid2room[room_id].addPlayer(info);
        let palyers = this.app.roomid2room[room_id].getPlayers();
        callback(MsgCode.JoinRoom, palyers);
    } else {
        callback(ErrorCode.Room_Nonexistence, []);
    }
};

/**
 * Add user into chat channel.
 * @param {Object} info user info object
 * @param {String} sid server id
 * @param {String} room_id channel name
 * @param {Function} callback
 */
Remote.prototype.joinRoom = function (info, sid, room_id, callback) {
    let channel = this.channelService.getChannel(room_id, false);
    if (!!channel) {
        channel.add(info['uid'], sid);

        // 房间中存在该uid则是断线续玩，否则为加入房间
        let is_exist = this.app.roomid2room[room_id].exist(info.uid);
        if (this.app.roomid2room[room_id].addPlayer(info)) {
            console.log('玩家【' + info.uid + '】加入房间【' + room_id + '】');
            let palyers = this.app.roomid2room[room_id].getPlayers();
            let options = this.app.roomid2room[room_id].getOpstions();
            let msg = {
                code: MsgCode.JoinRoom,
                data: {
                    map_id: this.map_id,
                    room_id: room_id,
                    options: options,
                    players: palyers
                }
            };

            // 1、断线续玩只给自己断线续玩则发送MsgCode.JoinRoom
            // 2、其他玩家MsgCode.OnlineStatus
            this.send(room_id, msg, is_exist ? info.uid : null);

            callback(msg);
        } else {
            console.log('房间【' + room_id + '】已经满员了！');
            callback({code: ErrorCode.Room_Full});
        }
    } else {
        callback({code: ErrorCode.Room_Nonexistence});
    }
};

/**
 * 游戏通知处理
 * @param {Object} msg
 * @param {Object} sid
 * @param {Function} next
 * */
Remote.prototype.onNotify = function (msg, sid, next) {
    console.info('Remote.prototype.onNotify:', msg, ' | sid:', sid);
    let code = msg['code'];
    let data = msg['data'];
    let uid = data['uid'];
    switch (code) {
        case MsgCode.CreateRoom:
            break;
        default:
            if (!data.hasOwnProperty('room_id')) {
                next(ErrorCode.Room_ID_Error);
                console.error('消息结构中没有【room_id】字段');
                break;
            }
            let room_id = msg['data']['room_id'];
            if (!this.app.roomid2room.hasOwnProperty(room_id)) {
                next(ErrorCode.Room_Nonexistence);
                console.error('房间不存在【' + room_id + '】');
                break;
            }
            // 进入房间处理逻辑
            let room = this.app.roomid2room[room_id];
            switch (code) {
                case MsgCode.LeaveRoom:
                    if (room.canLeaveRoom()) {
                        room.removePlayer(uid);
                        let channel = this.channelService.getChannel(room_id, false);
                        channel.leave(uid, sid);
                        if (room.canDestroy()) {
                            delete this.app.roomid2room[room_id];
                            console.info('删除房间【' + room_id + '】剩余房间', this.app.roomid2room);
                            next(MsgCode.DissolveRoom);
                            break;
                        }
                        next(MsgCode.LeaveRoom);
                    } else {
                        next('游戏中不能离开房间...');
                    }
                    break;
                default:
                    room.onNotify(msg, sid);// 这里交给房间自己处理
                    next('申请解散房间了...');
                    break;
            }
            break;
    }
};

/**
 * 用户注销处理
 * @param {String} uid 用户uid
 * @param {String} sid 后端服务器id（server_id）
 * @param {String} cid 信道id（channel_id）
 * @param {Function} callback 处理回调
 * */
Remote.prototype.logout = function (uid, sid, cid, callback) {
    let channel = this.channelService.getChannel(cid, false);
    if (!!channel) {
        channel.leave(uid, sid);
    }
    if (this.app.roomid2room.hasOwnProperty(cid)) {
        this.app.roomid2room[cid].logout(uid);
    } else {
        console.error('用户注销处理:Remote.prototype.logout');
    }
    callback();
};